home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / textfile.swg / 0046_File Browser Package.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-02-28  |  15.4 KB  |  608 lines

  1. {
  2. **************************************************************************
  3. *                                                                        *
  4. *     File Browser Package V1.0       by Daniel Perrenoud                *
  5. *     ~~~~~~~~~~~~~~~~~~~~~~~~~                                          *
  6. *     o Released to the Public domain, feel free to use and copy         *
  7. *       this program without any restriction.                            *
  8. *     o Please credit me if your program uses these routines.            *
  9. *     o Your comments are welcome. You can contact me on                 *
  10. *                                  e-mail: d_perren@kla.com              *
  11. *                                                                        *
  12. *                                  or by post:                           *
  13. *                                                                        *
  14. *                                  Daniel Perrenoud                      *
  15. *                                  Mont-Pugin 8                          *
  16. *                                  CH-2400 Le Locle                      *
  17. *                                  SWITZERLAND                           *
  18. *                                                                        *
  19. *     !!! Please compile me with range checking turned OFF  !!!          *
  20. *                                                                        *
  21. *                                                                        *
  22. **************************************************************************
  23.  
  24. This set of routine makes possible to display and walk through a text file
  25. of any length. The content of the currently selected line as well as the
  26. selected line number are available in global variables. The text file is
  27. diplayed in a window fully parametrable by the user (position, size,
  28. color). For better performance, use File Browser together with a disk
  29. caching program like MS-DOS SmartDrive.
  30.  
  31. Six functions and procedures are available for File Browser control:
  32.  
  33.  
  34. ---> Procedure InitFB(FN:str255;WUX,WUY,WLX,WLY,BC,FC,SBC,SFC:Word)
  35.      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  36.      InitFB initialises the File Browser and displays the first screen
  37.      of the file. The first line is selected.
  38.  
  39.      Parameters:  FN:       Path and file name to display (MS-DOS format)
  40.                   WUX,WUY:  Upper left corner of the window
  41.                   WLX,WLY:  Lower right corner of the window
  42.                   BC:       Background color of normal text
  43.                   FC:       Foreground color of normal text
  44.                   SBC:      Background color of selected line
  45.                   SFC:      Foreground color of selected line
  46.  
  47.  
  48.  
  49. ---> Function UpArrow:Boolean
  50.      ~~~~~~~~~~~~~~~~~~~~~~~~
  51.      UpArrow tries to select the previous line. It returns FALSE if the
  52.      previous line is not selectable because the top line is already
  53.      selected.
  54.  
  55.  
  56.  
  57. ---> Function DnArrow:Boolean
  58.      ~~~~~~~~~~~~~~~~~~~~~~~~
  59.      DnArrow tries to select the next line. It returns FALSE if the
  60.      next line is not selectable because the bottom line is already
  61.      selected.
  62.  
  63.  
  64.  
  65. ---> Function PgUp:Boolean
  66.      ~~~~~~~~~~~~~~~~~~~~~
  67.      PgUp tries to display the previous screen of text. If the top line
  68.      is reached before one complete screen has scrolled, PgUp returns
  69.      FALSE and only the possible number of lines is scrolled.
  70.  
  71.  
  72.  
  73. ---> Function PgDn:Boolean
  74.      ~~~~~~~~~~~~~~~~~~~~~
  75.      PgDn tries to display the next screen of text. If the bottom line
  76.      is reached before one complete screen has scrolled, PgDn returns
  77.      FALSE and only the possible number of lines is scrolled.
  78.  
  79.  
  80.  
  81. ---> Procedure CloseFB
  82.      ~~~~~~~~~~~~~~~~~
  83.      CloseFB stops File Browser activity. It must be used when FB is
  84.      no longer used in order to close the open files.
  85.  
  86.  
  87. The status of File Browser can be read through two variables:
  88.  
  89.  
  90. ---> SelAbsInd:Longint
  91.      ~~~~~~~~~~~~~~~~~
  92.      Selected line number. SelAbsInd=0 if the first line is selected.
  93.  
  94.  
  95. ---> Image[SelCirInd]:Str255
  96.      ~~~~~~~~~~~~~~~~~~~~~~~
  97.      Text of selected line. The CR or LF charaters have been removed.
  98.  
  99.  
  100.  
  101. This file is ready to be compiled by TP4.0 or better. A short example is
  102. included, showing how FB works.
  103.  
  104. CAUTION: FB routines change the window attributs by using the PASCAL
  105.          WINDOW procedure.
  106.  
  107.  
  108. Future extensions:
  109. ~~~~~~~~~~~~~~~~~~
  110. o Left and right scrolling to display long lines
  111. o Direct access to a specific line number
  112. o Find text module
  113. o Tag-untag line handling
  114. o Mouse support
  115. o Speed improvement by writing some ASM modules.
  116. o A decent error handling!
  117.  
  118. Let me know if you have other ideas ( e-mail: d_perren@kla.com )
  119. }
  120.  
  121.  
  122. program FileBrws;
  123.  
  124. uses           DOS,CRT;
  125.  
  126. type  Str255=String[255];
  127.  
  128. const NbRec=        255;
  129.       FrontCst=     0;
  130.       BackCst=      1;
  131.       CRcst=        $0D;
  132.       LFcst=        $0A;
  133.  
  134.  
  135. var   FileBrowse:                               array[0..2] of File;
  136.       CurLine,Packet:                           array[0..2] of Str255;
  137.       Image:                                    array[0..25] of Str255;
  138.       PacketInd,Numread:                        array[0..2] of Word;
  139.       FirstCirInd,ScrInd,SelCirInd:             Word;
  140.       MaxLine,VWUX,VWUY,VWLX,VWLY:              Word;
  141.       ColListBG,ColListFG,ColSListBG,ColSListFG:Word;
  142.       Ch,TmpChar:                               Char;
  143.       EndFile,EOP,Again,Dummy,ExtKey:           Boolean;
  144.       FileName:                                 Str255;
  145.       FilLinNum:                                Array[0..2] of Longint;
  146.       SelAbsInd:                                Longint;
  147.  
  148. Function WaitKey:Char;
  149. var   WK:         Char;
  150. begin
  151.   ExtKey:=FALSE;
  152.   repeat
  153.   until keypressed;
  154.   WK:=ReadKey;
  155.   if WK=#0 then
  156.   begin
  157.     ExtKey:=TRUE;
  158.     WK:=ReadKey;
  159.   end;
  160.   WaitKey:=WK
  161. end;
  162.  
  163. Procedure Initialize;
  164. begin
  165.   assign(FileBrowse[0],FileName);
  166.   assign(FileBrowse[1],FileName);
  167.   assign(FileBrowse[2],FileName);
  168.   reset(FileBrowse[0],1);
  169.   reset(FileBrowse[1],1);
  170.   reset(FileBrowse[2],1);
  171.   window(VWUX,VWUY,VWLX+1,VWLY);
  172.   ClrScr;
  173. end;
  174.  
  175. Procedure CloseFB;
  176. begin
  177.   close(FileBrowse[0]);
  178.   close(FileBrowse[1]);
  179.   close(FileBrowse[2]);
  180. end;
  181.  
  182. Procedure ReadPrevPacket(FN:integer);
  183. begin
  184.   seek(FileBrowse[FN],(FilePos(FileBrowse[FN])-Numread[FN]-NbRec));
  185.   blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
  186.   Packet[FN][0]:=chr(Numread[FN]);
  187.   PacketInd[FN]:=NbRec;
  188. end;
  189.  
  190. Function ReadNextLine(FN:integer):Boolean;
  191. var   EOP:        Boolean;
  192.       CurLinInd:  Word;
  193.  
  194. begin
  195.   ReadNextLine:=FALSE;
  196.   if (EndFile=FALSE) or (FN=BackCst) then
  197.   begin
  198.     CurLinInd:=1;
  199.     repeat
  200.       repeat
  201.         TmpChar:=Packet[FN][PacketInd[FN]];
  202.         CurLine[FN][CurLinInd]:=TmpChar;
  203.         inc(CurLinInd);
  204.         inc(PacketInd[FN]);
  205.         EOP:=(PacketInd[FN]>Length(Packet[FN]))
  206.       until ((ord(TmpChar)=CRcst) OR (EOP));
  207.       if EOP then
  208.         if Numread[FN]<>NbRec then
  209.           EndFile:=TRUE
  210.         else
  211.           begin
  212.             blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
  213.             Packet[FN][0]:=chr(Numread[FN]);
  214.             PacketInd[FN]:=1;
  215.           end;
  216.     until ((ord(TmpChar)=CRcst) or (EndFile));
  217.     ReadNextLine:=TRUE;
  218.     inc(FilLinNum[FN]);
  219.     CurLine[FN][0]:=chr(CurLinInd-1);
  220.   end;
  221. end;
  222.  
  223.  
  224. Procedure Read1stLine(FN:integer);
  225. var   CurLinInd:  Word;
  226.       EOP:        Boolean;
  227.  
  228. begin
  229.   EndFile:=FALSE;
  230.   reset(FileBrowse[FN],1);
  231.   blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
  232.   Packet[FN][0]:=chr(Numread[FN]);
  233.   PacketInd[FN]:=1;
  234.   CurLinInd:=1;
  235.   repeat
  236.     repeat
  237.       TmpChar:=Packet[FN][PacketInd[FN]];
  238.       CurLine[FN][CurLinInd]:=TmpChar;
  239.       inc(CurLinInd);
  240.       inc(PacketInd[FN]);
  241.       EOP:=(PacketInd[FN]>Length(Packet[FN]))
  242.     until ((ord(TmpChar)=CRcst) OR (EOP));
  243.     if EOP then
  244.       if Numread[FN]<>NbRec then
  245.         EndFile:=TRUE
  246.       else
  247.         begin
  248.           blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
  249.           Packet[FN][0]:=chr(Numread[FN]);
  250.           PacketInd[FN]:=1;
  251.         end;
  252.   until ((ord(TmpChar)=CRcst) or (EndFile));
  253.   CurLine[FN][0]:=chr(CurLinInd-1);
  254.   FilLinNum[FN]:=0;
  255. end;
  256.  
  257.  
  258. Function ReadPrevLine(FN:integer):Boolean;
  259. var   Dummy:      Boolean;
  260.       CurLinInd:  Word;
  261.       i:          Integer;
  262.  
  263. begin
  264.   CurLinInd:=1;
  265.   ReadPrevLine:=FALSE;
  266.   if FilLinNum[FN]>0 then
  267.   begin
  268.     if PacketInd[FN]>1 then
  269.       dec(PacketInd[FN])
  270.     else
  271.       ReadPrevPacket(FN);
  272.     TmpChar:=' ';
  273.     for i:=1 to 2 do
  274.     begin
  275.       while (ord(TmpChar)<>CRcst) and ((FilLinNum[FN]<>0) or (PacketInd[FN]<>1)) do
  276.       begin
  277.         if PacketInd[FN]>1 then
  278.           dec(PacketInd[FN])
  279.         else
  280.           ReadPrevPacket(FN);
  281.         TmpChar:=Packet[FN][PacketInd[FN]];
  282.       end;
  283.       TmpChar:=' ';
  284.       dec(FilLinNum[FN]);
  285.       EndFile:=FALSE;
  286.     end;
  287.     if FilLinNum[FN]<>-1 then
  288.       inc(PacketInd[FN]);
  289.     if PacketInd[FN]>Length(Packet[FN]) then
  290.     begin
  291.       blockread(FileBrowse[FN],Packet[FN][1],NbRec,Numread[FN]);
  292.       Packet[FN][0]:=chr(Numread[FN]);
  293.       PacketInd[FN]:=1;
  294.     end;
  295.     Dummy:=ReadNextLine(FN);
  296.     ReadPrevLine:=TRUE;
  297.   end;
  298. end;
  299.  
  300.  
  301. Function CleanString(ALine:str255):str255;
  302. var   i,j:        Integer;
  303.  
  304. begin
  305.   j:=1;
  306.   i:=1;
  307.   repeat
  308.     if (ord(ALine[i])<>CRcst) and (ord(ALine[i])<>LFcst) then
  309.     begin
  310.       CleanString[j]:=ALine[i];
  311.       inc(j);
  312.     end;
  313.     inc(i);
  314.   until (i>ord(ALine[0])) or (j>VWLX-VWUX+1);
  315.   CleanString[0]:=chr(j-1);
  316. end;
  317.  
  318.  
  319. Procedure DispSelLine;
  320.  
  321. begin
  322.   TextBackground(ColSListBG);
  323.   TextColor(ColSListFG);
  324.   GotoXY(1,ScrInd+1);
  325.   write(Image[SelCirInd]);
  326. end;
  327.  
  328.  
  329. Procedure UndispSelLine;
  330.  
  331. begin
  332.   TextBackground(ColListBG);
  333.   TextColor(ColListFG);
  334.   GotoXY(1,ScrInd+1);
  335.   write(Image[SelCirInd]);
  336. end;
  337.  
  338.  
  339. Function IncMod(i:Word):Word;
  340.  
  341. begin
  342.     IncMod:=(i+1) mod MaxLine;
  343. end;
  344.  
  345.  
  346. Function DecMod(i:Word):Word;
  347.  
  348. begin
  349.     DecMod:=(i+MaxLine-1) mod MaxLine;
  350. end;
  351.  
  352.  
  353. Procedure RefreshScreen;
  354. var   CleanLine:  Str255;
  355.       i,j:        Word;
  356.  
  357. begin
  358.   i:=FirstCirInd;
  359.   j:=1;
  360.   TextBackground(ColListBG);
  361.   TextColor(ColListFG);
  362.   ClrScr;
  363.   repeat
  364.     GotoXY(1,j);
  365.     write(Image[i]);
  366.     i:=IncMod(i);
  367.     inc(j);
  368.   until i=FirstCirInd;
  369.   DispSelLine;
  370. end;
  371.  
  372.  
  373. Procedure FirstScreen;
  374. var   CleanLine:  Str255;
  375.       i:          Integer;
  376.       LineOK:     Boolean;
  377.  
  378. begin
  379.   FirstCirInd:=0;
  380.   Read1stLine(FrontCst);
  381.   CleanLine:=CleanString(CurLine[FrontCst]);
  382.   Image[FirstCirInd]:=CleanLine;
  383.   TextBackground(ColListBG);
  384.   TextColor(ColListFG);
  385.   GotoXY(1,FirstCirInd+1);
  386.   write(CleanLine);
  387.   FirstCirInd:=IncMod(FirstCirInd);
  388.   repeat
  389.     LineOK:=ReadNextLine(FrontCst);
  390.     CleanLine:=CleanString(CurLine[FrontCst]);
  391.     Image[FirstCirInd]:=CleanLine;
  392.     GotoXY(1,FirstCirInd+1);
  393.     write(CleanLine);
  394.     FirstCirInd:=IncMod(FirstCirInd);
  395.   until (FirstCirInd=0) or (LineOK=FALSE);
  396.   Read1stLine(BackCst);
  397.   SelCirInd:=0;
  398.   SelAbsInd:=0;
  399.   ScrInd:=0;
  400.   DispSelLine;
  401. end;
  402.  
  403.  
  404. Function ScrollUp:Boolean;
  405. var   IsScrolled: Boolean;
  406.       Dummy:      Boolean;
  407.       CleanLine:  Str255;
  408.  
  409. begin
  410.   IsScrolled:=ReadNextLine(FrontCst);
  411.   if IsScrolled then
  412.   begin
  413.     CleanLine:=CleanString(CurLine[FrontCst]);
  414.     Image[FirstCirInd]:=CleanLine;
  415.     FirstCirInd:=IncMod(FirstCirInd);
  416.     TextBackground(ColListBG);
  417.     TextColor(ColListFG);
  418.     GotoXY(1,1);
  419.     DelLine;
  420.     GotoXY(1,MaxLine);
  421.     write(CleanLine);
  422.     Dummy:=ReadNextLine(BackCst);
  423.   end;
  424.   ScrollUp:=IsScrolled;
  425. end;
  426.  
  427.  
  428. Function ScrollDn:Boolean;
  429. var   IsScrolled: Boolean;
  430.       Dummy:      Boolean;
  431.       CleanLine:  Str255;
  432.  
  433. begin
  434.   IsScrolled:=ReadPrevLine(BackCst);
  435.   if IsScrolled then
  436.   begin
  437.     CleanLine:=CleanString(CurLine[BackCst]);
  438.     FirstCirInd:=DecMod(FirstCirInd);
  439.     Image[FirstCirInd]:=CleanLine;
  440.     TextBackground(ColListBG);
  441.     TextColor(ColListFG);
  442.     GotoXY(1,1);
  443.     InsLine;
  444.     GotoXY(1,1);
  445.     write(CleanLine);
  446.     Dummy:=ReadPrevLine(FrontCst);
  447.   end;
  448.   ScrollDn:=IsScrolled;
  449. end;
  450.  
  451.  
  452. Function DnArrow:Boolean;
  453. Var   Success:    Boolean;
  454.  
  455. begin
  456.   window(VWUX,VWUY,VWLX+1,VWLY);
  457.   UndispSelLine;
  458.   Success:=TRUE;
  459.   If IncMod(SelCirInd)=FirstCirInd then
  460.   begin
  461.     Success:=ScrollUp;
  462.     If Success then
  463.     begin
  464.       SelCirInd:=IncMod(SelCirInd);
  465.       inc(SelAbsInd);
  466.     end
  467.     else;
  468.   end
  469.   else
  470.   begin
  471.     SelCirInd:=IncMod(SelCirInd);
  472.     inc(SelAbsInd);
  473.     inc(ScrInd);
  474.   end;
  475.   DnArrow:=Success;
  476.   DispSelLine;
  477. end;
  478.  
  479.  
  480. Function UpArrow:Boolean;
  481. Var   Success:    Boolean;
  482.  
  483. begin
  484.   window(VWUX,VWUY,VWLX+1,VWLY);
  485.   UndispSelLine;
  486.   Success:=TRUE;
  487.   If SelCirInd=FirstCirInd then
  488.   begin
  489.     Success:=ScrollDn;
  490.     If Success then
  491.     begin
  492.       SelCirInd:=DecMod(SelCirInd);
  493.       Dec(SelAbsInd);
  494.     end
  495.     else;
  496.   end
  497.   else
  498.   begin
  499.     SelCirInd:=DecMod(SelCirInd);
  500.     dec(SelAbsInd);
  501.     dec(ScrInd);
  502.   end;
  503.   UpArrow:=Success;
  504.   DispSelLine;
  505. end;
  506.  
  507.  
  508. Function PgUp:Boolean;
  509. Var   Complete,Dummy:   Boolean;
  510.       i:                Word;
  511.       CleanLine:        Str255;
  512.  
  513. begin
  514.   window(VWUX,VWUY,VWLX+1,VWLY);
  515.   i:=MaxLine;
  516.   repeat
  517.     Complete:=ReadPrevLine(BackCst);
  518.     If Complete then
  519.     begin
  520.       CleanLine:=CleanString(CurLine[BackCst]);
  521.       FirstCirInd:=DecMod(FirstCirInd);
  522.       Image[FirstCirInd]:=CleanLine;
  523.       SelCirInd:=DecMod(SelCirInd);
  524.       Dec(SelAbsInd);
  525.       Dec(i);
  526.       Dummy:=ReadPrevLine(FrontCst);
  527.     end;
  528.   until (i=0) or (Complete=FALSE);
  529.   RefreshScreen;
  530. end;
  531.  
  532.  
  533. Function PgDn:Boolean;
  534. Var   Complete,Dummy:   Boolean;
  535.       i:                Word;
  536.       CleanLine:        Str255;
  537.  
  538. begin
  539.   window(VWUX,VWUY,VWLX+1,VWLY);
  540.   i:=MaxLine;
  541.   repeat
  542.     Complete:=ReadNextLine(FrontCst);
  543.     If Complete then
  544.     begin
  545.       CleanLine:=CleanString(CurLine[FrontCst]);
  546.       Image[FirstCirInd]:=CleanLine;
  547.       FirstCirInd:=IncMod(FirstCirInd);
  548.       SelCirInd:=IncMod(SelCirInd);
  549.       inc(SelAbsInd);
  550.       Dec(i);
  551.       Dummy:=ReadNextLine(BackCst);
  552.     end;
  553.   until (i=0) or (Complete=FALSE);
  554.   RefreshScreen;
  555. end;
  556.  
  557.  
  558. Procedure InitFB(FN:str255;WUX,WUY,WLX,WLY,BC,FC,SBC,SFC:Word);
  559.  
  560. begin
  561.   FileName:=FN;
  562.   ColListBG:=BC;
  563.   ColListFG:=FC;
  564.   ColSListBG:=SBC;
  565.   ColSListFG:=SFC;
  566.   VWUX:=WUX;
  567.   VWUY:=WUY;
  568.   VWLX:=WLX;
  569.   VWLY:=WLY;
  570.   MaxLine:=1+WLY-WUY;
  571.   Initialize;
  572.   FirstScreen;
  573. end;
  574.  
  575. {------------------- END OF FILE BROWSER MODULE ---------------------------}
  576.  
  577. {
  578. The following program shows a way to use the File Browser. It displays
  579. its own source code (!!) and handles the arrows and PgUp PgDn keys.
  580. The current line number and current line content are displayed on the
  581. bottom line.
  582. Be sure to place THIS source code (filebrws.pas) in the directory from
  583. which you run this program!
  584. Press q to quit.
  585. }
  586.  
  587. begin
  588.   ClrScr;
  589.   InitFB('Browse.pas',1,1,70,20,Black,LightGray,LightGray,Black);
  590.   repeat
  591.     Ch:=WaitKey;
  592.     if ExtKey then
  593.     begin
  594.       if Ch=#80 then Dummy:=DnArrow;
  595.       if Ch=#72 then Dummy:=UpArrow;
  596.       if Ch=#73 then Dummy:=PgUp;
  597.       if Ch=#81 then Dummy:=PgDn;
  598.       window(1,25,80,25);
  599.       TextBackground(ColListBG);
  600.       TextColor(ColListFG);
  601.       write(SelAbsInd);
  602.       write(':');
  603.       write(Image[SelCirInd]);
  604.     end;
  605.   until (ExtKey=FALSE) and (Ch='q');
  606.   CloseFB;
  607. end.
  608.